#ifndef CB97A48F_5B85_4F75_97C5_8647E54CFB3D
#define CB97A48F_5B85_4F75_97C5_8647E54CFB3D

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <thread>
#include <cstring>
#include <unistd.h>

const int size = 4096;

void Usage(const std::string &s)
{
	std::cout << "\n\t" << s << " serverip serverport" << std::endl;
}

class ThreadData
{
public:
	ThreadData()
	{}
	~ThreadData()
	{
		close(sockfd);
	}
public:
	struct sockaddr_in server;
	int sockfd;
};

void *recv_msg(void *args)
{
	ThreadData* td = static_cast<ThreadData*>(args);
	char buffer[size];
	while (true)
	{
		struct sockaddr_in temp;
		socklen_t len = sizeof(temp);
		ssize_t n = recvfrom(td->sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&temp, &len);
		if (n > 0)
		{
			buffer[n] = 0;
			std::cerr << buffer << std::endl;
			// std::cout << buffer << std::endl;
		}
	}
}

void *send_msg(void *args)
{
	ThreadData* td = static_cast<ThreadData*>(args);
	std::string msg;
	socklen_t len = sizeof(td->server);
	while(true)
	{
		std::cout << "Please Enter@ ";
		std::getline(std::cin, msg);
		sendto(td->sockfd, msg.c_str(), msg.size(), 0, (struct sockaddr *)&td->server, len);
	}
}

int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		Usage(argv[0]);
		return 0;
	}
	uint16_t port = std::stoi(argv[2]);
	std::cout << port << std::endl;
	std::string serverip = argv[1];
	std::cout << serverip << std::endl;

	ThreadData td;
	// struct sockaddr_in server;
	bzero(&td.server, sizeof(td.server));
	td.server.sin_addr.s_addr = inet_addr(serverip.c_str());
	td.server.sin_family = AF_INET;
	td.server.sin_port = htons(port); ///  必须转为大端

	td.sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (td.sockfd < 0)
	{
		std::cout << "socket error" << std::endl;
	}

	pthread_t recv_d, send_d;
	pthread_create(&recv_d, nullptr, recv_msg, &td);
	pthread_create(&send_d, nullptr, send_msg, &td);

	pthread_join(recv_d,nullptr);
	pthread_join(send_d,nullptr);

	close(td.sockfd);
	// std::string msg;
	// char buffer[size];
	// while (true)
	// {
	// 	std::cout << "Please Enter@ ";
	// 	std::getline(std::cin, msg);
	// 	sendto(sockfd, msg.c_str(), msg.size(), 0, (struct sockaddr *)&server, sizeof(server));

	// 	struct sockaddr_in temp;
	// 	socklen_t len = sizeof(temp);
	// 	ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&temp, &len);
	// 	if (n > 0)
	// 	{
	// 		buffer[n] = 0;
	// 		std::cout << buffer << std::endl;
	// 	}
	// }
	return 0;
}

#endif /* CB97A48F_5B85_4F75_97C5_8647E54CFB3D */
